package com.me.bbs.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.me.bbs.common.BanDuration;
import com.me.bbs.common.SessionUtils;
import com.me.bbs.dto.BanDTO;
import com.me.bbs.entity.Administrator;
import com.me.bbs.entity.Ban;
import com.me.bbs.entity.Forum;
import com.me.bbs.exceptions.NoAuthException;
import com.me.bbs.mapper.BanMapper;
import com.me.bbs.service.IAdministratorService;
import com.me.bbs.service.IBanService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.me.bbs.service.IForumService;
import com.me.bbs.service.IPostService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author lm
 * @since 2023-01-29
 */
@Service
public class BanServiceImpl extends ServiceImpl<BanMapper, Ban> implements IBanService {
    @Resource
    BanMapper banMapper;
    @Resource
    IForumService forumService;
    @Resource
    IAdministratorService administratorService;
    @Override
    public Page<BanDTO> searchUser(Long forumId, String q, Long current, Long size) {
        Page<BanDTO> banDTOPage = banMapper.searchUser(new Page(current, size), q, forumId);
        processWithDetail(banDTOPage);
        return banDTOPage;
    }

    @Override
    public Page<BanDTO> getBanList(Long forumId, Long current, Long size) {

        Page<BanDTO> banDTOPage = banMapper.queryBansPage(new Page(current,size), forumId);
        processWithDetail(banDTOPage);
        return banDTOPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void banUser(Long uid, Integer durationCode, Long forumId, String reason) {
        Boolean adminExists = administratorService.lambdaQuery().eq(Administrator::getUser,uid)
                .eq(Administrator::getForum,forumId)
                .exists();
        Boolean ownerExists = forumService.lambdaQuery().eq(Forum::getOwner, uid)
                .eq(Forum::getId, forumId)
                .exists();
        if(adminExists || ownerExists)
            throw new NoAuthException();
        Long bannedBy = (Long) SessionUtils.getAttribute("user");
        Ban ban = new Ban();
        ban.setBannedBy(bannedBy);
        ban.setUser(uid);
        ban.setDuration(durationCode);
        ban.setForum(forumId);
        ban.setReason(reason);
        BanDuration banDuration = BanDuration.getBanDurationByCode(durationCode);
        Integer hours = banDuration.getHours();
        if(hours == -1)
            ban.setExpireAt(null);
        else {
            LocalDateTime time = LocalDateTime.now();
            time = time.plusHours(hours);
            ban.setExpireAt(time);
        }
        this.save(ban);
    }

    private void processWithDetail(Page<BanDTO> banDTOPage) {
        List<BanDTO> records = banDTOPage.getRecords();
        records.forEach(v->{
            if(v.getDuration() != null)
                v.setDurationDetail(BanDuration.getBanDurationByCode(v.getDuration()).getDetail());
        });
    }
}
